﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Av.Utils;
using System.Net;

namespace WebUtils
{

    public delegate void SearchPageChangeDelegate(int page);

    public class SearchEventArgs : EventArgs
    {
        /// <summary>
        /// What domain we are checking
        /// </summary>
        public string DomainToSearchFor { get; set; }

        /// <summary>
        /// Keyword to search for
        /// </summary>
        public string Keyword { get; set; }

        public bool IsOk { get; set; }

        public bool IsFound { get; set; }

        /// <summary>
        /// Found at this position
        /// </summary>
        public int Position { get; set; }

        /// <summary>
        /// Offset in search results
        /// </summary>
        public int Offset { get; set; }

        /// <summary>
        /// Gets/sets result of search
        /// </summary>
        public string Result { get; set; }
    }

    public delegate void MyNotificationDelegate(object sender, SearchEventArgs args);

    public class GoogleSearchThread
    {

        public event MyNotificationDelegate SearchSucceded = null;

        public event MyNotificationDelegate SearchFinished = null;

        public event SearchPageChangeDelegate PageChanged = null;

        protected Thread m_thread = null;

        protected bool m_isWorking = false;
        /// <summary>
        /// Gets whether search is completed
        /// </summary>
        public bool IsWorking { get { return m_isWorking; } }

        public void Get(string domain, string kwd)
        {
            if(m_isWorking)
            {
                Log4cs.Log(Importance.Error, "Previous search is not finished, so excpet it!");
                throw new Exception("Previous search was not finished!");
            }

            //if( m_thread == null )
            //{
            //    m_thread = new Thread(new ParameterizedThreadStart(GetUrl));
            //    m_thread.Start(uri);
            //}

            SearchEventArgs e = new SearchEventArgs();
            e.DomainToSearchFor = domain;
            e.Keyword = kwd;
            e.IsOk = false;
            e.Result = null;
            e.Offset = 0;
            
            m_isWorking = true;
            m_thread = new Thread(new ParameterizedThreadStart(GetUrl));
            m_thread.Start(e);
        }

        protected WebClient m_webClient = new WebClient();
        private void GetUrl(object obj)
        {
            Log4cs.Log(Importance.Debug, "Starting search thread...");
            SearchEventArgs e = (SearchEventArgs)obj;
            string rlz = string.Format("1RHADBRcLT236LT236");
            string query = string.Format("http://www.google.com/search?pws=0&rlz={0}&ie=UTF-8&q={1}", rlz, e.Keyword);
            query = string.Format("http://www.google.lt/search?pws=0&rlz={0}&hl=lt&ie=UTF-8&q={1}", rlz, e.Keyword);
            string rq = query;

            try
            {
                while(m_isWorking)
                {
                    if(e.Offset > 0)
                    {
                        rq = string.Format("{0}&start={1}", query, e.Offset);
                    }
                    Log4cs.Log("Downloading data from: {0}...", rq);
                    byte[] ba = m_webClient.DownloadData(rq);
                    Log4cs.Log("Got {0} bytes", ba == null ? 0 : ba.Length);

                    if( PageChanged != null )
                    {
                        PageChanged(e.Offset / 10);
                    }

                    e.IsOk = true;
                    e.Result = Encoding.UTF8.GetString(ba);
                    SearchResultPage p = GoogleResultParser.Parse(e.Result);
                    if(p.ContainsDomain(e.DomainToSearchFor))
                    {
                        Log4cs.Log("Found search");
                        e.IsFound = true;
                        m_isWorking = false;
                        e.Position = e.Offset;
                        //Debug("Found");
                    } else
                    {
                        e.Offset += 10;
                        Thread.Sleep(500);
                        //Debug("Not found!");
                    }

                    if( e.Offset > 1000 )
                    {
                        m_isWorking = false;
                    }
                }

            } catch(Exception ex)
            {
                Log4cs.Log(Importance.Error, "Error getting data from requested URI!");
                Log4cs.Log(Importance.Debug, ex.ToString());

                e.Result = null;
                e.IsOk = false;
            }

            if(SearchFinished != null)
            {
                Log4cs.Log(Importance.Debug, "Firing SearchFinished event...");
                SearchFinished(this.ToString(), e);
            }
        }

    }
}
